package com.sohh.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;
import javax.xml.crypto.Data;

/**
 * @description:
 * @author: ruoan
 * @date: 2021/2/5 15:17
 */
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {


    @Autowired
    private UserDetailsService userDetailsService;

    // 注入数据源
    @Autowired
    private DataSource dataSource;
    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);
        //jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }


    /**
     * spring security 需要 PasswordEncoder的实现类
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /**
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());

    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.formLogin() //自定义登录页
            .loginPage("/login.html")  // 默认登录页面, 这里 / 不能少
            .loginProcessingUrl("/login")  //处理登录post的路径，不需要自己实现登录逻辑，由spring security实现；需要和前端表单的post的路径一致
            .defaultSuccessUrl("/main.html").permitAll()  //如果是直接从登录页login.html登录，就会走/hello指定的逻辑；而如果是从其他路径跳到login.html登录页，则登录完成后，会直接回调到那个接口
            .and().authorizeRequests()
                .antMatchers("/","/hello2").permitAll()
                //.antMatchers("/hello3").hasAuthority("happy2") //登录后，该角色需要有happy权限，才能访问到/hello3
                //.antMatchers("/hello3").hasRole("admin") //登录后，该角色需要属于admin角色，才能访问到/hello3 ,
                // 针对同一个路径，后写的才生效，这里对Authority为happy2的设置不生效
            .anyRequest().authenticated()
            .and().rememberMe().tokenRepository(persistentTokenRepository())
            .tokenValiditySeconds(60)  //指定60s后cookie过期
            .userDetailsService(userDetailsService);
            //.and().csrf().disable();
        //自定义403无权限的页面
        http.exceptionHandling().accessDeniedPage("/unauth.html");
        //自定义注销页面
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login.html").permitAll();

    }
}
